use fltk::{
    frame::Frame,
    enums::{FrameType, Color, LabelType},
    menu::Choice,
    // text::{TextBuffer},
    button::Button,
    group::Group,
    prelude::*,
    input::Input,
};

use std::sync::mpsc::Sender;
use crate::common::event::AppEvent;
use crate::common::event::EventSender;

// 公共常量
const PADDING: i32 = 8;
const LABEL_HEIGHT: i32 = 14;
const BTN_HEIGHT: i32 = 22;
const GROUP_SPACING: i32 = 8;
const GROUP_LABEL_HEIGHT: i32 = 20;
const LABEL_SIZE: i32 = 12;
const CIRCLE_BTN_SIZE: i32 = 16;

// 颜色常量
const COLOR_SYSTEM_BG: Color = Color::from_rgb(240, 240, 240);  // 系统界面背景色
const COLOR_WHITE: Color = Color::White;  // 纯白色
const COLOR_TEXT: Color = Color::from_rgb(0, 0, 0);  // 文本颜色
const COLOR_APP_BG: Color = Color::from_rgb(238, 238, 238);  // 应用背景色

// 公共特征，用于统一设置控件样式
trait CommonStyle {
    fn set_common_style(&mut self, label_type: LabelType);
}

impl CommonStyle for Frame {
    fn set_common_style(&mut self, label_type: LabelType) {
        self.set_label_type(label_type);
        self.set_label_color(COLOR_TEXT);
        self.set_label_size(LABEL_SIZE);
    }
}

impl CommonStyle for Button {
    fn set_common_style(&mut self, _label_type: LabelType) {
        self.set_frame(FrameType::UpBox);
        self.set_color(COLOR_SYSTEM_BG);
        self.set_label_color(COLOR_TEXT);
        self.set_label_size(LABEL_SIZE);
        self.set_selection_color(COLOR_APP_BG);
    }
}

impl CommonStyle for Group {
    fn set_common_style(&mut self, _label_type: LabelType) {
        self.set_frame(FrameType::EngravedBox);
        self.set_color(COLOR_SYSTEM_BG);
        self.set_label_size(LABEL_SIZE);
        self.set_align(fltk::enums::Align::TopLeft);
        self.set_label_color(COLOR_TEXT);
    }
}

// 网络设置组件，包含协议选择、地址端口输入、连接按钮等
struct NetSetting {
    group: Group,
    lbl_protocol: Frame,
    cmb_protocol: Choice,
    lbl_remote_addr: Frame,
    txt_remote_addr: Input,
    lbl_port: Frame,
    txt_port: Input,
    btn_connect: Button,
    msg_tx: EventSender,
}

impl NetSetting {
    fn new(x: i32, y: i32, w: i32, _h: i32, msg_tx: EventSender) -> Self {
        let padding = 15;
        let item_height = 22;
        let label_spacing = 2;
        let connect_btn_height = 30;

        let total_height = (LABEL_HEIGHT + label_spacing + item_height) * 3
                          + GROUP_SPACING * 2
                          + connect_btn_height + 10
                          + padding * 2;

        let mut group = Group::new(x, y + GROUP_LABEL_HEIGHT, w, total_height, "网络设置");
        group.set_common_style(LabelType::Normal);

        let content_x = x + padding;
        let content_y = y + GROUP_LABEL_HEIGHT + padding;
        let content_w = w - (padding * 2);

        // 协议类型标签与选择框
        let mut lbl_protocol = Frame::new(content_x, content_y, content_w, LABEL_HEIGHT, "协议类型");
        lbl_protocol.set_common_style(LabelType::Normal);

        let mut cmb_protocol = Choice::new(content_x, content_y + LABEL_HEIGHT + label_spacing, content_w, item_height, "");
        cmb_protocol.add_choice("UDP|TCP Client|TCP Server");
        cmb_protocol.set_text_size(LABEL_SIZE);
        cmb_protocol.set_color(COLOR_SYSTEM_BG);
        cmb_protocol.set_selection_color(COLOR_APP_BG);

        let cmd_msg_tx = msg_tx.clone();
        cmb_protocol.set_callback(move |c| {
            println!("协议选择框: {}", c.value());
            let selected_index = c.value() as u32;
            cmd_msg_tx.send(AppEvent::EventProtocolChanged{protocol : c.value() as u32});
        });

        // 远程地址标签与输入框
        let addr_y = content_y + LABEL_HEIGHT + label_spacing + item_height + GROUP_SPACING;
        let mut lbl_remote_addr = Frame::new(content_x, addr_y, content_w, LABEL_HEIGHT, "远程主机");
        lbl_remote_addr.set_common_style(LabelType::Normal);

        let mut txt_remote_addr = Input::new(content_x, addr_y + LABEL_HEIGHT + label_spacing, content_w, item_height, "");
        txt_remote_addr.set_frame(FrameType::DownBox);
        txt_remote_addr.set_color(COLOR_WHITE);
        txt_remote_addr.set_text_color(COLOR_TEXT);
        txt_remote_addr.set_text_size(LABEL_SIZE);

        txt_remote_addr.handle(Box::new(move |input: &mut Input, ev: fltk::enums::Event| {
            if ev == fltk::enums::Event::KeyDown {
                let current_text = input.value();
                if current_text.len() >= 255
                    && fltk::app::event_key() != fltk::enums::Key::BackSpace
                    && fltk::app::event_key() != fltk::enums::Key::Delete {
                    return true;
                }
            }
            false
        }));

        // 端口标签与输入框
        let port_y = addr_y + LABEL_HEIGHT + label_spacing + item_height + GROUP_SPACING;
        let mut lbl_port = Frame::new(content_x, port_y, content_w, LABEL_HEIGHT, "端口号");
        lbl_port.set_common_style(LabelType::Normal);

        let mut txt_port = Input::new(content_x, port_y + LABEL_HEIGHT + label_spacing, content_w, item_height, "");
        txt_port.set_frame(FrameType::DownBox);
        txt_port.set_color(COLOR_WHITE);
        txt_port.set_text_color(COLOR_TEXT);
        txt_port.set_text_size(LABEL_SIZE);

        txt_port.handle(Box::new(move |input: &mut Input, ev: fltk::enums::Event| {
            if ev == fltk::enums::Event::KeyDown {
                let key = fltk::app::event_key();
                if key != fltk::enums::Key::BackSpace && key != fltk::enums::Key::Delete {
                    let key_text = fltk::app::event_text();
                    if !key_text.chars().all(|c| c.is_ascii_digit()) {
                        return true;
                    }
                    let current_text = input.value();
                    let new_text = format!("{current_text}{key_text}");
                    if new_text.len() >= 5 || new_text.parse::<u32>().unwrap_or(0) > 65535 {
                        return true;
                    }
                }
            }
            false
        }));

        // 连接按钮
        let btn_y = port_y + LABEL_HEIGHT + label_spacing + item_height + 10;
        let mut btn_connect = Button::new(content_x, btn_y, content_w, connect_btn_height, "连接");
        btn_connect.set_common_style(LabelType::Normal);

        let btn_con_msg_tx = msg_tx.clone();
        let mut is_connected = false;
        btn_connect.set_callback(move |btn| {
            if is_connected {
                println!("连接按钮: 断开");
                btn.set_label("连接");
                is_connected = false;
            } else {
                println!("连接按钮: 连接");
                btn.set_label("断开");
                is_connected = true;
            }

            btn_con_msg_tx.send(AppEvent::EventConnected{e_is_connected : is_connected});
        });

        group.end();

        Self { group, lbl_protocol, cmb_protocol, lbl_remote_addr,
               txt_remote_addr, lbl_port, txt_port, btn_connect, msg_tx}
    }

    fn height(&self) -> i32 {
        self.group.height() + GROUP_LABEL_HEIGHT
    }
}

// 接收设置组件，包含HEX显示切换、清空和保存按钮
struct RecvSetting {
    group: Group,
    lbl_hex_recv: Frame,
    btn_hex_recv: Button,
    btn_clear_recv: Button,
    btn_save_recv: Button,
    msg_tx: EventSender,
}

impl RecvSetting {
    fn new(x: i32, y: i32, w: i32, h: i32, msg_tx: EventSender) -> Self {
        let group_height = h - GROUP_LABEL_HEIGHT;
        let mut group = Group::new(x, y + GROUP_LABEL_HEIGHT, w, group_height, "接收设置");
        group.set_common_style(LabelType::Normal);

        let content_x = x + PADDING;
        let content_y = y + GROUP_LABEL_HEIGHT + PADDING;
        let content_w = w - (PADDING * 2);

        let mut lbl_hex_recv = Frame::new(content_x, content_y, 50, LABEL_HEIGHT, "HEX显示");
        lbl_hex_recv.set_common_style(LabelType::Normal);

        let mut btn_hex_recv = Button::new(content_x + 55, content_y + (LABEL_HEIGHT - CIRCLE_BTN_SIZE)/2,
                                         CIRCLE_BTN_SIZE, CIRCLE_BTN_SIZE, "");
        btn_hex_recv.set_frame(FrameType::RoundDownBox);
        btn_hex_recv.set_color(COLOR_SYSTEM_BG);
        btn_hex_recv.set_selection_color(COLOR_APP_BG);

        let event_hex_recv = msg_tx.clone();
        let mut hex_recv_on = false;
        btn_hex_recv.set_callback(move |b| {
            hex_recv_on = !hex_recv_on;
            if hex_recv_on {
                b.set_label("•");
                b.set_label_color(COLOR_TEXT);
                b.set_label_size(20);
                println!("HEX显示: 开启");
            } else {
                b.set_label("");
                println!("HEX显示: 关闭");
            }

            event_hex_recv.send(AppEvent::EventHexRecvShow{is_hex : hex_recv_on});
            b.redraw();
        });

        let clear_y = content_y + BTN_HEIGHT + GROUP_SPACING;
        let mut btn_clear_recv = Button::new(content_x, clear_y, content_w, 24, "清空接收区");
        btn_clear_recv.set_common_style(LabelType::Normal);

        let btn_clear_msg_tx = msg_tx.clone();
        btn_clear_recv.set_callback(move |_| {
            println!("清空接收区按钮: 点击");
            btn_clear_msg_tx.send(AppEvent::EventClearRecv);
        });

        let save_y = clear_y + 24 + GROUP_SPACING;
        let mut btn_save_recv = Button::new(content_x, save_y, content_w, 24, "保存数据");
        btn_save_recv.set_common_style(LabelType::Normal);

        let btn_save_msg_tx = msg_tx.clone();
        btn_save_recv.set_callback(move |_| {
            println!("保存接收区数据按钮: 点击");
            btn_save_msg_tx.send(AppEvent::EventSaveRecv);
        });

        group.end();

        Self { group, lbl_hex_recv, btn_hex_recv, btn_clear_recv, btn_save_recv, msg_tx}
    }

    fn height(&self) -> i32 {
        self.group.height() + GROUP_LABEL_HEIGHT
    }
}

// 发送设置组件，包含HEX发送切换、定时发送相关控件
struct SendSetting {
    group: Group,
    lbl_hex_send: Frame,
    btn_hex_send: Button,
    lbl_timer: Frame,
    txt_timer: Input,
    lbl_timer_unit: Frame,
    btn_timer: Button,
    msg_tx: EventSender,
}

impl SendSetting {
    fn new(x: i32, y: i32, w: i32, _h: i32, msg_tx: EventSender) -> Self {
        let mut group = Group::new(x, y + GROUP_LABEL_HEIGHT, w, 130, "发送设置");
        group.set_common_style(LabelType::Normal);

        let content_x = x + PADDING;
        let content_y = y + GROUP_LABEL_HEIGHT + PADDING;
        let content_w = w - (PADDING * 2);

        let mut lbl_hex_send = Frame::new(content_x, content_y, 50, LABEL_HEIGHT, "HEX发送");
        lbl_hex_send.set_common_style(LabelType::Normal);

        let mut btn_hex_send = Button::new(content_x + 55, content_y + (LABEL_HEIGHT - CIRCLE_BTN_SIZE)/2,
                                         CIRCLE_BTN_SIZE, CIRCLE_BTN_SIZE, "");
        btn_hex_send.set_frame(FrameType::RoundDownBox);
        btn_hex_send.set_color(COLOR_SYSTEM_BG);
        btn_hex_send.set_selection_color(COLOR_APP_BG);

        let btn_msg_tx = msg_tx.clone();
        let mut hex_send_on = false;
        btn_hex_send.set_callback(move |b| {
            hex_send_on = !hex_send_on;
            if hex_send_on {
                b.set_label("•");
                b.set_label_color(COLOR_TEXT);
                b.set_label_size(20);
                println!("HEX发送: 开启");
            } else {
                b.set_label("");
                println!("HEX发送: 关闭");
            }
            btn_msg_tx.send(AppEvent::EventHexSend{is_hex : hex_send_on});
            b.redraw();
        });

        let timer_y = content_y + BTN_HEIGHT + GROUP_SPACING;
        let mut lbl_timer = Frame::new(content_x, timer_y, 50, LABEL_HEIGHT, "定时发送");
        lbl_timer.set_common_style(LabelType::Normal);

        let mut txt_timer = Input::new(content_x + 55, timer_y, 40, BTN_HEIGHT, "");
        txt_timer.set_frame(FrameType::DownBox);
        txt_timer.set_color(COLOR_WHITE);
        txt_timer.set_text_color(COLOR_TEXT);
        txt_timer.set_text_size(LABEL_SIZE);

        let mut lbl_timer_unit = Frame::new(content_x + 100, timer_y + 4, 20, LABEL_HEIGHT, "ms");
        lbl_timer_unit.set_common_style(LabelType::Normal);

        let btn_y = timer_y + BTN_HEIGHT + GROUP_SPACING;
        let mut btn_timer = Button::new(content_x, btn_y, content_w, 24, "定时发送");
        btn_timer.set_common_style(LabelType::Normal);

        let btn_msg_tx = msg_tx.clone();
        btn_timer.set_callback(move |_| {
            println!("定时发送按钮: 点击");
            btn_msg_tx.send(AppEvent::EventButtonTimer);
        });

        group.end();
        Self { group, lbl_hex_send, btn_hex_send, lbl_timer,
               txt_timer, lbl_timer_unit, btn_timer, msg_tx}
    }

    fn height(&self) -> i32 {
        150
    }
}

// 左侧面板整体封装，组合网络、接收、发送设置组件
pub struct LeftPanel {
    background: Group,
    net_setting: NetSetting,
    recv_setting: RecvSetting,
    send_setting: SendSetting,
    msg_tx: EventSender,
}

impl LeftPanel {
    pub fn new(_app_width: i32, app_height: i32, start_x: i32, start_y: i32, tx: Sender<AppEvent>) -> Self {
        let panel_width = 180;
        let msg_tx = EventSender::new(tx);

        let mut background = Group::new(start_x, start_y, panel_width, app_height, "");
        background.set_color(COLOR_APP_BG);

        let net_setting = NetSetting::new(start_x, start_y, panel_width, 0, msg_tx.clone());
        let net_height = net_setting.height();

        let send_setting = SendSetting::new(start_x,
                                          app_height - 150 - GROUP_SPACING,
                                          panel_width, 0, msg_tx.clone());

        let recv_y = start_y + net_height + GROUP_SPACING;
        let recv_height = app_height - recv_y - send_setting.height() - GROUP_SPACING * 2 - GROUP_SPACING;
        let recv_setting = RecvSetting::new(start_x, recv_y, panel_width, recv_height, msg_tx.clone());

        background.end();
        Self { background, net_setting, recv_setting, send_setting, msg_tx }
    }

    pub fn get_coordinates(&self) -> (i32, i32, i32, i32) {
        (0, 0, 180, self.net_setting.height() +
                    self.recv_setting.height() +
                    self.send_setting.height() + GROUP_SPACING * 2)
    }

    pub fn handle_event(&mut self, event: &AppEvent) {
        println!("LeftPanel handleEvent {:?}", event);
    }
}
